package com.szl.sbssh.service.impl;

import com.szl.sbssh.constants.Constants;
import com.szl.sbssh.constants.GlobalConstant;
import com.szl.sbssh.jpa.OrganizationRepository;
import com.szl.sbssh.jpa.RoleRepository;
import com.szl.sbssh.jpa.UserRepository;
import com.szl.sbssh.model.Torganization;
import com.szl.sbssh.model.Tresource;
import com.szl.sbssh.model.Trole;
import com.szl.sbssh.model.Tuser;
import com.szl.sbssh.pageModel.base.PageFilter;
import com.szl.sbssh.pageModel.base.SessionInfo;
import com.szl.sbssh.pageModel.sys.User;
import com.szl.sbssh.service.UserService;
import com.szl.sbssh.utils.DateUtil;
import com.szl.sbssh.utils.MD5Util;
import com.szl.sbssh.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import javax.transaction.Transactional;
import java.util.*;

/**
 * Author: songzhonglin
 * Date: 2018/4/17
 * Time: 9:50
 * Description:
 **/
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private OrganizationRepository organizationRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Override
    public List<User> dataGrid(User user, PageFilter ph) {
        Pageable pageable =null;
        if(ph.getOrder().equals("asc")){
            pageable= new PageRequest(ph.getPage() -1 , ph.getRows(), new Sort(Sort.Direction.ASC, ph.getSort()));
        }else{
            pageable= new PageRequest(ph.getPage() -1 , ph.getRows(), new Sort(Sort.Direction.DESC, ph.getSort()));
        }
        Page<Tuser> userPage = userRepository.findAll(new Specification<Tuser>() {
            List<Predicate> list = new ArrayList<Predicate>();

            @Nullable
            @Override
            public Predicate toPredicate(Root<Tuser> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                whereSql(root, cb,user,list);
                Predicate[] p = new Predicate[list.size()];
//                query.where(p);
                //return query.where(list.toArray(p)).getRestriction();
                return cb.and(list.toArray(new Predicate[list.size()]));
//                return null;

//                Predicate p1 = cb.like(root.get("name").as(String.class), "%" + user.getName() + "%");
//                Predicate p2 = cb.equal(root.get("id").as(Integer.class), user.getId());
//                Predicate p3 = cb.gt(root.get("age").as(Integer.class), um.getAge());
                //把Predicate应用到CriteriaQuery中去,因为还可以给CriteriaQuery添加其他的功能，比如排序、分组啥的
//                query.where(cb.and(p1));

//                return query.getRestriction();

            }
        }, pageable);
        List<Tuser> tuserList = userPage.getContent();
        List<User> ul = new ArrayList<User>();
        for (Tuser t : tuserList) {
            User u = new User();
            BeanUtils.copyProperties(t, u);
//            u.setSexName(sysDictionaryServiceI.getNameByCode(t.getSex()));
//            u.setUserTypeName(sysDictionaryServiceI.getNameByCode(t.getUsertype()));
            Set<Trole> roles = t.getRoles();
            if ((roles != null) && !roles.isEmpty()) {
                String roleIds = "";
                String roleNames = "";
                boolean b = false;
                for (Trole tr : roles) {
                    if (b) {
                        roleIds += ",";
                        roleNames += ",";
                    } else {
                        b = true;
                    }
                    roleIds += tr.getId();
                    roleNames += tr.getName();
                }
                u.setRoleIds(roleIds);
                u.setRoleNames(roleNames);
            }
            if (t.getOrganization() != null) {
                u.setOrganizationId(t.getOrganization().getId());
                u.setOrganizationName(t.getOrganization().getName());
            }
            ul.add(u);
        }
        return ul;
    }

    @Override
    public Long count(User user, PageFilter ph) {

        Long count = userRepository.count(new Specification<Tuser>() {
            List<Predicate> list = new ArrayList<Predicate>();
            @Nullable
            @Override
            public Predicate toPredicate(Root<Tuser> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                whereSql(root, cb,user,list);
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(new Predicate[list.size()]));
                //return query.where(list.toArray(p)).getRestriction();

            }
        });
        return count;
    }

    private void whereSql(Root<Tuser> root, CriteriaBuilder cb,User user,List<Predicate> list) {
        list.add(cb.in(root.get("")));
        if(StringUtil.isNotEmpty(user.getName())){
            list.add(cb.like(root.get("name").as(String.class), "%"+user.getName()+"%"));
        }
        if(StringUtil.isNotEmpty(user.getOrganizationId())){
            list.add(cb.equal(root.get("organization").get("id").as(Long.class), user.getOrganizationId()));
        }
        if (StringUtil.isNotEmpty(user.getCreatedatetimeStart())) {
            list.add(cb.greaterThanOrEqualTo(root.get("createdatetime").as(Date.class), DateUtil.stringToDate(user.getCreatedatetimeStart(),"yyyy-MM-dd HH:mm:ss")));
        }
        if (StringUtil.isNotEmpty(user.getCreatedatetimeEnd())) {
            list.add(cb.lessThanOrEqualTo(root.get("createdatetime").as(Date.class), DateUtil.stringToDate(user.getCreatedatetimeEnd(),"yyyy-MM-dd HH:mm:ss")));
        }
    }

    @Override
    public void add(User u) {
        Tuser t = new Tuser();
        BeanUtils.copyProperties(u, t);
        Torganization org = organizationRepository.findById(u.getOrganizationId()).get();
        t.setOrganization(org);
        List<Trole> roles = new ArrayList<Trole>();
        if (u.getRoleIds() != null) {
            for (String roleId : u.getRoleIds().split(",")) {
                roles.add(roleRepository.findById(Long.valueOf(roleId)).get());
            }
        }
        t.setRoles(new HashSet<Trole>(roles));
        t.setPassword(MD5Util.md5(u.getPassword()));
        if (!Constants.SUPERADMIN.equals(u.getUsertype())) {
            t.setIsdefault(GlobalConstant.NOT_DEFAULT);
        } else {
            t.setIsdefault(GlobalConstant.DEFAULT);
        }
        t.setCreatedatetime(new Date());
        userRepository.save(t);
    }

    @Override
    public void delete(Long id) {
        userRepository.deleteById(id);
    }

    @Override
    public void edit(User user) {

    }

    @Override
    public User get(Long id) {
        return null;
    }

    @Override
    public User login(User user) {

        List<Tuser> tuserList = userRepository.findByLoginnameAndPassword(user.getLoginname(), MD5Util.md5(user.getPassword()));

        if (tuserList.size() > 0) {
            User u = new User();
            BeanUtils.copyProperties(tuserList.get(0), u);
            return u;
        }
        return null;
    }

    @Override
    public List<String> listResource(Long id) {
        List<String> resourceList = new ArrayList<String>();
        List<Tuser> t = userRepository.findAll(new Specification<Tuser>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<Tuser> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Join<Tuser, Trole> tuserTroleJoin = root.join("roles", JoinType.INNER).join("resources", JoinType.INNER);

                Predicate p2 = cb.equal(root.get("id").as(Long.class), id);
                query.where(p2);
                return query.getRestriction();
            }
        });

        if (t != null && t.size() > 0) {
            Set<Trole> roles = t.get(0).getRoles();
            if ((roles != null) && !roles.isEmpty()) {
                for (Trole role : roles) {
                    Set<Tresource> resources = role.getResources();
                    if ((resources != null) && !resources.isEmpty()) {
                        for (Tresource resource : resources) {
                            System.out.println("请求地址："+resource.getUrl());
                            if ((resource != null) && (StringUtils.isNotBlank(resource.getUrl()))) {
                                resourceList.add(resource.getUrl());
                                resourceList.add(resource.getUrl() + "/" + resource.getState());
                            }
                        }
                    }
                }
            }
        }
        return resourceList;
    }

    @Override
    public boolean editUserPwd(SessionInfo sessionInfo, String oldPwd, String pwd) {
        return false;
    }

    @Override
    public User getByLoginName(User user) {
        Tuser t  = userRepository.findByLoginname(user.getLoginname());
        User u = new User();
        if (t != null) {
            BeanUtils.copyProperties(t, u);
        } else {
            return null;
        }
        return u;
    }

    @Override
    public List<User> getUserListByUserType() {
        return null;
    }

    @Override
    public String[] getUserListNameByUserType() {
        return new String[0];
    }

    @Override
    public List<User> exportExcelBySelect(String ids) {
        return null;
    }
}
